/**
 *
 * @returns {string}
 */
export function guid() {
  return 'xxxxxxxx-xxxx-4xxx-yxxx-xxxxxxxxxxxx'.replace(/[xy]/g, function (c) {
    var r = Math.random() * 16 | 0,
      v = c == 'x' ? r : (r & 0x3 | 0x8);
    return v.toString(16);
  });
}

export function totalReduceNum(arr) {
  return arr.reduce(function (total, item) {
    return total + item.value || 0;
  }, 0);
}

/**
 * 防抖
 * @param {Function} func
 * @param {number} wait
 * @param {boolean} immediate
 * @return {*}
 */
export function debounce(func, wait, immediate) {
  let timeout, args, context, timestamp, result

  const later = function () {
    // 据上一次触发时间间隔
    const last = +new Date() - timestamp

    // 上次被包装函数被调用时间间隔 last 小于设定时间间隔 wait
    if (last < wait && last > 0) {
      timeout = setTimeout(later, wait - last)
    } else {
      timeout = null
      // 如果设定为immediate===true，因为开始边界已经调用过了此处无需调用
      if (!immediate) {
        result = func.apply(context, args)
        if (!timeout) context = args = null
      }
    }
  }

  return function (...args) {
    context = this
    timestamp = +new Date()
    const callNow = immediate && !timeout
    // 如果延时不存在，重新设定延时
    if (!timeout) timeout = setTimeout(later, wait)
    if (callNow) {
      result = func.apply(context, args)
      context = args = null
    }

    return result
  }
}

/**
 *
 * @param dom
 * @param callback
 */
export function observerDomResize(dom, callback) {
  const MutationObserver = window.MutationObserver || window.WebKitMutationObserver || window.MozMutationObserver

  const observer = new MutationObserver(callback)

  observer.observe(dom, {attributes: true, attributeFilter: ['style'], attributeOldValue: true})

  return observer
}


/**
 * 日期格式化
 * @param fmt
 * @param date
 * @returns {*}
 */
export function formatDate(fmt, date) {
  let myDate = date ? new Date(date) : new Date()

  fmt = fmt || 'yyyy-MM-dd'
  const o = {
    'M+': myDate.getMonth() + 1, // 月份
    'd+': myDate.getDate(), // 日
    'h+': myDate.getHours(), // 小时
    'm+': myDate.getMinutes(), // 分
    's+': myDate.getSeconds(), // 秒
    'q+': Math.floor((myDate.getMonth() + 3) / 3), // 季度
    'S': myDate.getMilliseconds() // 毫秒
  }
  if (/(y+)/.test(fmt)) {
    fmt = fmt.replace(RegExp.$1, (myDate.getFullYear() + '').substr(4 - RegExp.$1.length))
  }
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(fmt)) {
      fmt = fmt.replace(RegExp.$1, (RegExp.$1.length == 1) ? (o[k]) : (('00' + o[k]).substr(('' + o[k]).length)))
    }
  }
  return fmt
}

export function getDayArray(day = 7) {
  let dayArr = [];
  let oneDay = 24 * 60 * 60 * 1000
  for (let i = 0; i < day; i++) {
    dayArr.unshift(formatDate("yyyy-MM-dd", new Date(Date.now() - i * oneDay)))
  }
  return dayArr
}

export function getDayArrayObj(day = 7) {
  let dayArr = [];
  let oneDay = 24 * 60 * 60 * 1000
  for (let i = 0; i < day; i++) {
    dayArr.unshift({
      'yyyy-MM-dd': formatDate("yyyy-MM-dd", new Date(Date.now() - i * oneDay)),
      'yyyyMMdd': formatDate("yyyyMMdd", new Date(Date.now() - i * oneDay)),
      'MM-dd': formatDate("MM-dd", new Date(Date.now() - i * oneDay)),
      'today': i === 0
    })
  }
  return dayArr
}

/**
 * 区间随机数
 * @param istart
 * @param iend
 * @param round // 整数
 * @returns {number}
 */
export function getRandom(istart, iend, round = false) {
  let iChoice = iend - istart
  let num = Math.random() * iChoice + istart
  if (round) {
    return Math.round(num)
  } else {
    return num
  }
}

/**
 * 列表集合生成树 （tree） 用于字典表数据的转换
 * @param list
 * @param props // 赋值的字段 如将原有的 name 字段赋值给 label
 * @returns {[]}
 */
export function hierarchiesToTree(list, props = {label: 'name'}) {
  let arrMap = new Map()
  list.forEach((item, index) => {
    item.newhierarchies = item.hierarchies.replace(/^\/|\/$/g, "") || '/'
    let pnames = item.newhierarchies.split('/')
    Object.keys(props).forEach(key => {
      item[key] = item[props[key]]
    })
    if (pnames.length > 1) {
      item.pkname = pnames[pnames.length - 2]
      item.kname = pnames[pnames.length - 1]
    } else if (pnames.length === 1) {
      item.pkname = 0
      item.kname = pnames[0]
    } else {
      item.pkname = 0
      item.kname = 0
    }
    arrMap.set(item.newhierarchies, item)
  })
  const nodeMap = new Map()
  const result = []
  // 第一遍循环使用对象将每项添加一个 children
  for (const node of [...arrMap.values()]) {
    if (node['children'] && node['children'].length) {
      node['children'] = node['children']
    }
    nodeMap.set(node['kname'], node)
  }
  // 第二遍循环将【每项放到对应的父级下】，如果没有则父级放到result
  for (const node of list) {
    const parent = nodeMap.get(node['pkname'])
    if (parent) {
      parent['children'] ? parent['children'].push(node) : parent['children'] = [node]
    } else {
      result.push(node)
    }
  }

  return result
}

/**
 * 列表集合生成树 （tree） 根据id
 * @param list
 * @param pid  开始pid
 * @returns {[]}
 */
export function listToTreeById(list, pid) {
  const nodeMap = new Map()
  const result = []
  // 第一遍循环使用对象将每项添加一个 children
  for (const node of list) {
    node['children'] = node['children'] || []
    nodeMap.set(node['id'], node)
  }
  // 第二遍循环将【每项放到对应的父级下】，如果没有则父级放到result
  for (const node of list) {
    const parent = nodeMap.get(node['pid'])
    if (parent) {
      parent['children'].push(node)
    } else {
      result.push(node)
    }
  }
  return result
}

// 将数组转二维数组
export function to2DArray(arr, subArrayLength) {
  // 计算二维数组的长度
  const numChunks = Math.ceil(arr.length / subArrayLength);
  const newArray = Array(numChunks);

  for (let i = 0, j = 0; i < arr.length; i += subArrayLength, j++) {
    newArray[j] = arr.slice(i, i + subArrayLength);
  }

  return newArray;
}
